<?php

namespace App\Models;

use Illuminate\Support\Arr;
use Illuminate\Database\Eloquent\Model;
use App\Models\XcSiteOrder;
use App\Models\XcSiteWashMode;
use Illuminate\Support\Facades\DB;

class XcUserRecharge extends Model
{
    protected $table = 'xc_user_recharge';
    protected $guarded = ['id'];

    protected $appends = ['type_name'];

    public function user()
    {
        return $this->belongsTo('App\Models\XcUser', 'user_id', 'id');
    }

    public function getTypeNameAttribute()
    {
        return $this->attributes['type_name'] = Arr::get([1 => '充值订单', 2 => '年卡订单', 3 => '季卡订单', 4 => '月卡订单', 5 => '次卡订单', 6 => '单次消费订单'], $this->type);
    }

    /**
     * 充值变动
     * @param $order
     * @param $type 1、充值赠送 2、订单消耗
     * @param $site_name
     */
    public static function doRecharge($order, $type, $site_name = '')
    {
        if ($type == 1) {
            $money = $order->valid_price ?? $order->pay_price;
            $points = $order->points;
            $money_history = $order->pay_price;
        } else {
            $money = (-1) * $order->valid_price;
            $points = $order->points;
            $money_history = 0;
        }

        //更新积分和余额
        (new XcUser())->updateMoneyAndPoints($order->user_id, $money, $points, $money_history);

        //变动类型1、充值赠送 2、订单消耗, 1金额，2积分

        //金额赠送
        (new XcUserConsumerDetails())->changeLog($order->user_id, $money, $type, $order->order_sn, 1, $site_name);

        //积分
        (new XcUserConsumerDetails())->changeLog($order->user_id, $points, $type, $order->order_sn, 2, $site_name);
    }

    /**
     * 会员卡及次卡充值
     * @param $order
     */
    public static function doCardRecharge($order)
    {
        $user = XcUser::where('id', $order->user_id)->first();

        $recharge_setting = XcRechargeSetting::where('id', $order->recharge_setting_id)->first();

        //1-充值卡，2-年卡，3-季卡，4-月卡，5-次卡
        if ($recharge_setting->type == 5) {

            $exp_now = date('Y-m-d');

            $member_exp = date('Y-m-d', strtotime("+{$recharge_setting->valid_year} year", strtotime($exp_now)));

            $user->updateNum($order->user_id, $order->fast_washing_num, $order->fine_washing_num, $order->pay_price);

            //次卡充值记录
            $order->fast_washing_num ? (new XcUserConsumerDetails())->changeLog($order->user_id, $order->fast_washing_num, 1, $order->order_sn, 3, '', 0, 1) : '';

            $order->fine_washing_num ? (new XcUserConsumerDetails())->changeLog($order->user_id, $order->fine_washing_num, 1, $order->order_sn, 3, '', 0, 2) : '';

        } else {

            if ($recharge_setting->fine_washing_num > 0) {
                $field = 'fine_member_exp';
                $exp_now = $user->fine_member_exp;
                $day = $recharge_setting->fine_washing_num;
            } else {
                $field = 'fast_member_exp';
                $exp_now = $user->fast_member_exp;
                $day = $recharge_setting->fast_washing_num;
            }

            if ($exp_now < date('Y-m-d H:m:s') || !$exp_now) {
                $exp_now = date('Y-m-d');
            }

            $member_exp = date('Y-m-d', strtotime("+{$day} day", strtotime($exp_now)));

            $user->update(["{$field}" => $member_exp]);

            $user->increment('money_history', $order->pay_price);
        }

        $order->update([
            'start_time' => $exp_now,
            'end_time' => $member_exp
        ]);
    }

    /**
     * 获各指定用户的充值卡信息
     * 排除掉 type = 6的所有合法数据
     * 1充值卡2年卡3季卡4月卡5次卡6单次购买订单
     *
     * 2,3,4 需要有效期，且每天只能使用一次
     * 5每天不限次数，也是有效期，是否用完。有可能一个用户买多张次卡
     *
     * 注：2023-12-12最终讨论结果，用户最终扣款列表：会员卡、次卡、余额、积分、即充即用 这几种方式支付
     *             其中：会员卡包括：年卡、季卡、月卡；这三种按照购买时间先后给出一个，即始终展示最先购买的卡先用
     *
     */
    public function GetUserRechargeArra($userid, $openid, $sw_id)
    {
        $type_arra           = [2 => '年卡', 3 => '季卡', 4 => '月卡', 5 => '次卡'];
        $user_recharge_arra  = [];//存储用户当前会员卡列表
        $ctime               = date("Y-m-d H:i:s");
        $cicard_min_arra     = [];//用户多个次卡,用于存储ID 和到期时间
        $cicard_recharge_seting_ids = [];

        //获得当前站点洗车模式，如果站点只有精洗，则用户购买的精洗卡才能展示出来
        $site    = XcSiteWashmode::where('id', $sw_id)->first();
        if (empty($site)) return [];

        $recharge = $this->whereIn('type', [2,3,4,5])->where([['user_id', '=', $userid],['pay_status', '=', 2]]);
        /*
        if (!empty($site) && $site->washing_type == 1){
            $recharge = $recharge->where([['fast_washing_num', '>', 0]]);
        }
        if (!empty($site) && $site->washing_type == 2){
            $recharge = $recharge->where([['fine_washing_num', '>', 0]]);
        }
        */
        $recharge = $recharge->orderby("created_at", 'asc')->get();

        //查找当天是有使用过
        $so_arra = XcSiteOrder::where([['openid', '=', $openid],['status','=', 1]])->whereRaw("SUBSTRING(created_at,1,10) ='".date("Y-m-d")."'")->pluck("type")->toArray();

        if (!empty($recharge)){
            //判断各卡有效期以及种条件,分两种情况:
            //1:年卡、季卡、月卡需要判断有效期，用一天只能使用一次
            //2.次卡需要判断有效期，如果有多个次卡的时候，还需要返回最先到期的次卡
            foreach($recharge as $k => $v)
            {
                if (in_array($v->type, [2,3,4]) && ($ctime >= $v->start_time && $ctime <= $v->end_time) )
                {
                    if (empty($so_arra) || !in_array($v->type, $so_arra)){
                        $user_recharge_arra[$v->type][] = ['type'             => $v->type,
                                                         'user_recharge_id' => $v->id,
                                                         'recharge_setting_id' => $v->recharge_setting_id,
                                                         'name' => $type_arra[$v->type]
                                                     ];
                    }
                //次卡比较复杂的是，用户可能购买多个次卡，此情况需要返回最快到期的次卡
                }else if ($v->type == 5 && ($ctime >= $v->start_time && $ctime <= $v->end_time) && ($v->used_washing_num < $v->washing_num )){
                    $cicard_min_arra[$v->id] = $v->end_time;
                    $cicard_recharge_seting_ids[$v->id] = $v->recharge_setting_id;
                }
            }

            //dd($user_recharge_arra);
            //取会员卡的第一个元素,例：如果有
            if (!empty($user_recharge_arra)) {
                $temp_arra = array_shift($user_recharge_arra);
                unset($user_recharge_arra);
                $user_recharge_arra[$temp_arra[0]['type']] = $temp_arra[0];
            }
            //dd($user_recharge_arra);

            //如果有多张次卡，则需要按照到期日期进行升序排序，然后返回最第一个，即最快到期的那个
            if (!empty($cicard_min_arra)) {
                asort($cicard_min_arra);
                $cicard_id_arra = array_keys($cicard_min_arra);
                $id = $cicard_id_arra[0]??0;
                $user_recharge_arra[5] = [
                    'type' => 5,
                    'user_recharge_id' => $id,
                    'recharge_setting_id' => $cicard_recharge_seting_ids[$id]??0,
                    'name' => '次卡'];
            }
        }

        return array_values($user_recharge_arra);
    }

    /**
     * 用户会员卡/次卡详情
     * @param $user_id
     * @param $type 5次卡，2、3、4 会员卡
     * @return array
     */
    public function userRechargeInfo($user_id, $type)
    {

        /* 次卡/会员卡数据统计：
              订单情况：订单总数，已结束，待启用，使用中，总次，使用次数
              启用订单：订单类型，到期时间，购卡金额，使用次数，使用金额，可退款金额
       */

        $data = [];

        $card_sql = $this->where('pay_status', 2)->where('user_id', $user_id)->orderBy('id', 'ASC');

        if ($type == 5) {
            $card_sql->where('type', 5);
        } else {
            $card_sql->whereIn('type', [2, 3, 4]);
        }

        //订单总数
        $query_sql = clone $card_sql;
        $data['total_order_num'] = $query_sql->count();

        //已结束订单数
        $query_sql = clone $card_sql;
        $data['finish_order_num'] = $query_sql->whereRaw("(end_time <= CURRENT_TIMESTAMP() OR (fine_washing_num = used_fine_washing_num AND fast_washing_num = used_fast_washing_num))")->count();

        //总次数
        $query_sql = clone $card_sql;
        $data['total_num'] = $query_sql->sum(DB::raw('fine_washing_num+fast_washing_num'));

        //使用次数
        $query_sql = clone $card_sql;
        $data['using_num'] = $query_sql->sum(DB::raw('used_fine_washing_num+used_fast_washing_num'));

        //使用中订单
        $data['using_order_num'] = 0;

        $query_sql = clone $card_sql;
        $list = $query_sql->select('id', 'order_sn', 'pay_price', 'fine_washing_num', 'used_fine_washing_num', 'fast_washing_num', 'used_fast_washing_num', 'start_time', 'end_time', 'type')->whereRaw("end_time > CURRENT_TIMESTAMP() AND (fine_washing_num > used_fine_washing_num OR fast_washing_num > used_fast_washing_num)")->get();

        foreach ($list as $value) {

            if ($value->used_fine_washing_num > 0 || $value->used_fast_washing_num > 0) {
                $value->used_price = $value->used_fine_washing_num * 19.9 + $value->used_fast_washing_num * 9.9;
                $data['using_order_num']++;
            } else {
                $value->used_price = 0;
            }

            $value->suggest_refund_price = $value->pay_price - $value->used_price;
        }

        $data['valid_data'] = $list->toArray();

        return $data;
    }

    /**
     * 用户充值卡详情
     * @param $user_id
     * @return array
     */
    public function userRechargeMoneyInfo($user_id)
    {

        /* 充值卡数据统计：
              订单情况：订单总金额，订单总数，已完成订单，进行中订单
              (进行中订单) 积分：赠送总积分，账户积分，已使用，转化为金额
              (进行中订单) 余额：订单总金额，账户余额， 扣除积分使用，可退金额
       */

        $data = [];

        $card_sql = $this->where('type', 1)->where('pay_status', 2)->where('user_id', $user_id);

        //订单总金额
        $query_sql = clone $card_sql;
        $data['total_order_price'] = $query_sql->sum('pay_price');

        //订单总数
        $query_sql = clone $card_sql;
        $data['total_order_num'] = $query_sql->count();

        //未完成订单数量
        $query_sql = clone $card_sql;
        $list = $query_sql->where('status', 2)->select('id', 'order_sn', 'pay_price', 'valid_price', 'points', 'type')->orderBy('id', 'DESC')->get()->toArray();

        //(进行中订单)赠送总积分
        $data['total_points'] = array_sum(array_column($list, 'points'));

        //(进行中订单)订单总金额
        $data['total_price'] = array_sum(array_column($list, 'valid_price'));

        //账户余额
        $data['total_plus_price'] = XcUserConsumerDetails::where('change_type', 1)->where('user_id', $user_id)->sum('num');

        //剩余积分
        $total_plus_points = XcUserConsumerDetails::where('change_type', 2)->where('user_id', $user_id)->sum('num');

        //已使用积分
        $data['total_used_points'] = $data['total_points'] - $total_plus_points;

        //扣除积分使用
        $data['points_price'] = $data['total_used_points'] / 10;

        $data['suggest_refund_price'] = $data['total_plus_price'] - $data['points_price'];

        //进行中订单数量
        $data['unfinished_order_num'] = 0;

        $data['valid_data'] = [];

        //如果余额为0
        if ($data['total_plus_price'] <= 0) {
            $query_sql = clone $card_sql;
            $query_sql->where('status', 2)->update(['status' => 3]);
        } else {

            //余额不为0时，计算未完成订单退款情况
            $base_price = 0;
            $base_points = 0;
            $using_price_flag = 0;
            $using_points_flag = $total_plus_points > 0 ? 0 : 1;

            foreach ($list as $key => &$value) {

                $base_price += $value['valid_price'];
                $base_points += $value['points'];

                //未完成订单记数
                if (!$using_price_flag) {
                    $data['unfinished_order_num']++;
                } else {
                    //已完成订单更改状态
                    $value->update(['status' => 3]);
                    continue;
                }

                //未开始的订单
                $refund_price = $value['valid_price'];
                //进行中订单
                if ($base_price > $data['total_plus_price']) {
                    $using_price_flag = 1;
                    $refund_price = $refund_price - ($base_price - $data['total_plus_price']);
                }

                //未开始的积分
                $refund_points = $value['points'];
                //进行中的订单查看积分是否使用
                if ($using_points_flag) {
                    $refund_points = 0;
                } elseif ($base_points > $total_plus_points && !$using_points_flag) {
                    $using_points_flag = 1;
                    $refund_points = $value['points'] - ($base_points - $total_plus_points);
                }

                $value['refund_price'] = $refund_price;
                $value['refund_points'] = $refund_points;
                $value['used_points'] = $value['points'] - $refund_points;
                $value['suggest_refund_price'] = $value['refund_price'] - $value['used_points'] / 10;

                $data['valid_data'][] = $value;
            }
            unset($value);
        }

        return $data;
    }

}
